package com.syni.mdd.sjb.community.base.controller.protect;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.syni.mdd.sjb.common.component.mybatis.community.entity.WxCorpBusinessRelation;
import com.syni.mdd.sjb.common.component.mybatis.community.entity.WxExternalContact;
import com.syni.mdd.sjb.common.component.utils.common.spring.ApplicationContextHolder;
import com.syni.mdd.sjb.common.component.utils.common.utils.*;
import com.syni.mdd.sjb.community.base.constants.Constants;
import com.syni.mdd.sjb.community.base.constants.ResultCode;
import com.syni.mdd.sjb.community.base.constants.ResultMsg;
import com.syni.mdd.sjb.community.base.entity.bo.UserData;
import com.syni.mdd.sjb.community.base.entity.vo.rp.auth.GetSameCompanyUsersRpVo;
import com.syni.mdd.sjb.community.base.entity.vo.rq.auth.BindDxshAppVo;
import com.syni.mdd.sjb.community.base.entity.vo.rq.auth.GetExternalcontactVo;
import com.syni.mdd.sjb.community.base.listener.SyncExternalcontactEvent;
import com.syni.mdd.sjb.community.base.service.WxCorpBusinessRelationService;
import com.syni.mdd.sjb.community.base.service.WxExternalContactService;
import com.syni.mdd.sjb.community.base.service.WxPermanentCodeService;
import com.syni.mdd.sjb.community.base.service.impl.CommonUtilsServceImpl;
import com.syni.mdd.sjb.community.base.utils.MybatisUtils;
import com.syni.mdd.sjb.community.base.utils.OAUtils;
import com.syni.mdd.sjb.community.base.utils.TokenUtils;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Controller
@RequestMapping("/auth")
@Log4j2
public class AppAuthorizationController {
    @Autowired
    CommonUtilsServceImpl commonUtilsServce;

    @Autowired
    WxPermanentCodeService wxPermanentCodeService;

    @Value("${login.redict.url:http://dg.syni.com}")
    private String loginRedictUrl;

    @Value("${app.index.url:http://dg.syni.com}")
    private String appIndexUrl;

    @Autowired
    WxExternalContactService wxExternalContactService;

    @Autowired
    WxCorpBusinessRelationService wxCorpBusinessRelationService;

    @GetMapping("/getProviderToken")
    @ResponseBody
    public Map<String, Object> getProviderToken() {
        //final WxCpService wxCpService = WxCpConfiguration.getCpService(wxCpProperties.getAppConfigs().get(0).getAgentId());
        //WxCpProviderToken wxCpProviderToken = wxCpService.getProviderToken(wxCpProperties.getCorpId(),wxCpProperties.getAppConfigs().get(0).getSecret());
        //System.out.println(wxCpProviderToken);
        //commonUtilsServce.test();
        return ResultMapHelper.success();
    }


    @GetMapping(value = "/webLogin")
    public void webLogin(@RequestParam("scope") String scope,HttpServletResponse rp) throws IOException {
        String appId = AppConfig.getProperty("SuiteID");
        String redirectUri = URLEncoder.encode(loginRedictUrl,"UTF-8");
        String url = String.format("https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&scope=%s&state=STATE#wechat_redirect",
                appId,redirectUri,scope);
        log.info("跳转url:" + url);
        rp.sendRedirect(url);
    }

    @GetMapping("/userInfo")
    public void userInfo(HttpServletRequest request, HttpServletResponse response,String code) throws IOException {
        String suite_access_token = OAUtils.getSuiteAccessToken();
        String url = "https://qyapi.weixin.qq.com/cgi-bin/service/getuserinfo3rd?suite_access_token=" + suite_access_token + "&code=" + code;
        String responseBody = RestTemplateUtils.getForEntity(url,new HashMap<>());
        log.info("userInfo：{}",responseBody);
        if(StringUtils.isNotBlank(responseBody)) {
            JSONObject jsonObj = JSON.parseObject(responseBody);
            String userTicket = jsonObj.getString("user_ticket");
            if (StringUtils.isNotBlank(userTicket)) {
                try {
                    jsonObj.putAll(OAUtils.getUserDetail3rd(userTicket));
                } catch (Exception e) {
                    log.error(e.getMessage(), e);
                }
            }
            String userId = jsonObj.getString("UserId");
            String open_userid = jsonObj.getString("open_userid");
            String corpId = jsonObj.getString("CorpId");
            UserData userData = new UserData(userId, open_userid,corpId,System.currentTimeMillis());
            String pageToken = JWT.create().withAudience(JSON.toJSONString(userData))
                    .sign(Algorithm.HMAC256(WebUtils.MD5(corpId + userId)));
            log.info("pageToken:{}",pageToken);
            String redirectUrl = String.format("%s?userToken=%s", appIndexUrl, pageToken);
            log.info("redirectUrl:" + redirectUrl);
            wxCorpBusinessRelationService.handleCorpBusinessAuthReleation(userData.getCorpId());
            ApplicationContextHolder.getApplicationContext().publishEvent(new SyncExternalcontactEvent("",userData.getCorpId()));
            response.sendRedirect(redirectUrl);

        }
    }

    @PostMapping("/getExternalcontact")
    @ResponseBody
    public Map<String,Object> getExternalcontact(@RequestBody GetExternalcontactVo getExternalcontactVo){
        RequestHeaderData requestHeaderData = new RequestHeaderData();
        String userToken = requestHeaderData.getString("usertoken");
        String referer = requestHeaderData.getString("referer");
        if(StringUtils.isNotBlank(referer) && referer.indexOf("userToken") != -1){
            String[] referers = referer.split("userToken");
            if(referers.length > 1){
                userToken = referers[1].substring(1);
                log.info(userToken);
            }
        }
        if(userToken.endsWith("/")){
            userToken = userToken.substring(0,userToken.length() - 1);
        }
        if(userToken.endsWith("#")){
            userToken = userToken.substring(0,userToken.length() - 1);
        }
        QueryWrapper queryWrapper = new QueryWrapper();
        UserData userData = TokenUtils.checkH5UserToken(userToken);
        if(userData == null){
            return ResultMapHelper.result(ResultCode.CODE_ERROR_100,ResultMsg.CODE_ERROR_PARAM_LOSE);
        }
        String name = getExternalcontactVo.getName();
        if(StringUtils.isNotBlank(name)){
            queryWrapper.like(WxExternalContact.NAME,name);
        }
        queryWrapper.eq(WxExternalContact.CORPID,userData.getCorpId());
        IPage iPage = new Page(getExternalcontactVo.getPageNum(),getExternalcontactVo.getPageSize());
        IPage<WxExternalContact> wxExternalContacts = wxExternalContactService.page(iPage,queryWrapper);
        Map<String,Object> resultUserData = MybatisUtils.UserData(iPage);
        resultUserData.put("isBindDxshApp", Constants.COMMON_FLAG_FALSE_INT);
        queryWrapper.clear();
        queryWrapper.eq(WxCorpBusinessRelation.CORPID,userData.getCorpId());
        int wxCorpBusinessRelationsCount = wxCorpBusinessRelationService.count(queryWrapper);
        if(wxCorpBusinessRelationsCount > 0){
            resultUserData.put("isBindDxshApp", Constants.COMMON_FLAG_TRUE_INT);
        }
        List<WxExternalContact> wxResult = wxExternalContacts.getRecords();
        List<GetSameCompanyUsersRpVo> getSameCompanyUsersRpVos = BeanUtils.copyList(wxResult,GetSameCompanyUsersRpVo.class);
        return ResultMapHelper.success(getSameCompanyUsersRpVos,resultUserData,ResultMsg.MSG_GET_SUCCESS);
    }

    @PostMapping("/bindDxshApp")
    @ResponseBody
    public Map<String,Object> bindDxshApp(@RequestBody BindDxshAppVo bindDxshAppVo){
        RequestHeaderData requestHeaderData = new RequestHeaderData();
        String userToken = requestHeaderData.getString("usertoken");
        String referer = requestHeaderData.getString("referer");
        if(StringUtils.isNotBlank(referer) && referer.indexOf("userToken") != -1){
            String[] referers = referer.split("userToken");
            if(referers.length > 1){
                userToken = referers[1].substring(1);
                log.info(userToken);
            }
        }
        if(userToken.endsWith("/")){
            userToken = userToken.substring(0,userToken.length() - 1);
        }
        if(userToken.endsWith("#")){
            userToken = userToken.substring(0,userToken.length() - 1);
        }
        UserData userData = TokenUtils.checkH5UserToken(userToken);
        if(userData == null){
            return ResultMapHelper.result(ResultCode.CODE_ERROR_100,ResultMsg.CODE_ERROR_PARAM_LOSE);
        }
        boolean isHaveResult = wxCorpBusinessRelationService.handleCorpBusinessAuthReleationByPhone(userData.getCorpId(),bindDxshAppVo.getPhone());
        if(!isHaveResult){
            return ResultMapHelper.result(ResultCode.CODE_NO_SEARCH_RESULT,ResultMsg.MSG_NO_SEARCH_RESULT);
        }
        return ResultMapHelper.success(null,ResultMsg.HAND_SUCCESS);
    }
}
